1 Introduction

  • In this notebook, we present the first results of an analysis of green development paths of Nordic regions
  • It is based on patent data from 1990-2015 (PATSTAT, Autumn 2021 Edition)
  • Analysis is done on all Nordic NUTS 2 regions (fractionalized patent allocation by inventor location, DOCDB family level)
  • Industries are captured by NACE2 codes of patents according to the OECD IPC-NACE2 concordance table.
  • Green patents are identified using the Y02 tag in the CPC classification

1.1 Preprocessing

### general options
Sys.setenv(LANG = "en")
options("scipen" = 100, "digits" = 4) # override R's tendency to use scientific notation

### Clean workspace
rm(list=ls())
graphics.off()

### Load packages (maybe need to be installed first)
# Standard
library(tidyverse) # General DS toolkit
library(magrittr) # For advanced piping

# Databases
library(DBI) # GEneral R database interface
library(RPostgres) # PostgreSQL interface driver 
library(dbplyr) # for dplyr with databases

# networks
library(tidygraph)
library(ggraph)
library(ggrepel)

# Load functions
source("functions/functions_relatedness.R")
## LOAD DATA

# Regular tables
data_appln <- read_rds('../temp/data_appln.rds')
data_docdb_fam_cpc <- read_rds('../temp/data_docdb_fam_cpc.rds')
data_pers_appln  <- read_rds('../temp/data_pers_appln.rds')
data_person <- read_rds('../temp/data_person.rds')
data_nace2 <- read_rds('../temp/data_nace2.rds')

# Adittional ones
g_tech <- read_rds('../temp/g_tech.rds')
region_RTA <- read_rds('../temp/region_RTA.rds')
region_tech <- read_rds('../temp/region_tech.rds')
## SELECT FOCUS REGIONS

## Defining parameters
n_regions = 10
n_cutoff = 25
reg_in = c('SE232', 'NO043', 'DK012')

# Restrict to top N regions
select_region <- region_tech %>%
  group_by(nuts) %>%
  summarise(n = sum(weight_frac, na.rm = TRUE),
            n_Y = sum(weight_frac * Y_tag, na.rm = TRUE)) %>%
  ungroup() %>%
  mutate(share_Y = n_Y / (n + n_Y)) %>%
  filter(n_Y >= n_cutoff) %>%
  arrange(desc(n_Y)) %>%
  mutate(index = 1:n()) %>%
  filter(index <= n_regions | nuts %in% reg_in) %>%
  distinct(nuts) %>%
  pull(nuts)

rm(n_regions, reg_in)
# Createdataframe with technology relatedness edgelist
tech_rel <- g_tech %E>%
  mutate(from_nace = .N()$name[from],
         to_nace = .N()$name[to]) %>%
  as_tibble() %>%
  mutate(from = from_nace %>% as.character(),
         to = to_nace %>% as.character(),
         pct_rank = weight %>% percent_rank()) %>%
  arrange(from, to) %>%
  select(from, to, weight, pct_rank)

tech_rel %<>%
  bind_rows(tech_rel %>% 
              rename(from_new = to, to_new = from) %>% 
              rename(from = from_new, to = to_new) %>%
              relocate(from, to)) %>%
  distinct(from, to, .keep_all = TRUE)
# augment regions data 
# NOTE: DO earlier already in construction
region_RTA %<>%
  mutate(country = nuts %>% str_sub(1,2)) 
# Summarize Regions
region_RTA_agg <- region_RTA %>%
  group_by(nuts, period, Y_tag) %>%
  summarise(n_spec = rta_bin %>% sum(na.rm = TRUE),
            n_spec_count = (n_tech_region * rta_bin) %>% sum(na.rm = TRUE),
            HHI = sum((n_tech_region/sum(n_tech_region) * 100)^2) ) %>%
  ungroup() %>%
  mutate(country = nuts %>% str_sub(1,2),
    nuts_period = paste(nuts, 'P', period)) 
`summarise()` has grouped output by 'nuts', 'period'. You can override using the `.groups` argument.

2 Patent application development

  • In the following, a brief descriptive analysis of the development of green and non-green patent application in the Nordics
  • In addition, a breackdown of green patents by top green patenting reagions
# Dataframe with regions and technology fields
tech_dev <- region_RTA %>%
  select(period, country, nuts, nace_group, Y_tag, n_tech_region, rta, rta_bin) %>%
  arrange(nuts, nace_group, Y_tag, period) 

tech_dev %<>% 
  group_by(nuts, nace_group, Y_tag) %>%
  mutate(rta_dev = case_when(
    rta_bin < lag(rta_bin, 1)  ~ -1,
    rta_bin == lag(rta_bin, 1)  ~ 0,
    rta_bin > lag(rta_bin, 1)  ~ 1 
  )) %>%
  ungroup()
data_appln %>%
  count(appln_filing_year, Y_tag) %>%
  ggplot(aes(x = appln_filing_year, y = n, col = Y_tag)) + 
  geom_line(key_glyph = "timeseries") +
  labs(title = 'Patent applications: Development',
       subtitle = 'All Nordic contries, by Y tag',
       x = 'Year',
       y = 'Number applications',
       col = 'Green')

3 Technology space general

  • We calculate the relatedness of industries by co-occurence pattern following Hidalgo & Hausmann (2007)
  • Revealed technological advantage (RTA) Is sepperatedly calculated for Y-tag and non-Y-tag patents.
data_pers_appln %>%
  filter(nuts %in% select_region) %>%
  count(appln_filing_year, nuts, Y_tag, wt = weight_frac) %>%
  ggplot(aes(x = appln_filing_year, y = n, col = nuts)) + 
  geom_line(key_glyph = "timeseries") +
  facet_wrap(vars(Y_tag), scales = 'free') +
  labs(title = 'Patent applications: Development',
       subtitle = 'All Nordic contries',
       x = 'Year',
       y = 'Number applications, by region and Y tag',
       col = 'Nuts3')

set.seed(1337)
coords_tech <- g_tech %>% igraph::layout.fruchterman.reingold() %>% as_tibble()
colnames(coords_tech) <- c("x", "y")

4 Regional specialization (RTA) development

  • Comparison of specialization provides in period 1 and 2
g_tech %N>%
  mutate(nace_group_name = nace_group_name %>% str_trunc(50, side = 'right')) %>%
  ggraph(layout =  coords_tech) + 
  geom_edge_link(aes(width = weight, alpha = weight), colour = "grey") + 
  geom_node_point(aes(colour = nace_sec_name, size = dgr)) + 
  geom_node_text(aes(label = nace_group_name, size = dgr, filter = percent_rank(dgr) >= 0.5 ), repel = TRUE) +
  theme_void() +
  theme(legend.position="bottom") + 
  labs(title = 'Industry Space (all Nordics)',
       subtitle = 'Nodes = NACE 2 Industries. Edges: Relatedness')

p1 <- region_RTA_agg  %>%
  filter(nuts %in% select_region) %>%
  pivot_wider(names_from = Y_tag, values_from = c(n_spec, n_spec_count, HHI), values_fill = 0, names_prefix = 'Y_tag_') 

p2 <- p1 %>% 
  select(period, nuts, n_spec_Y_tag_FALSE, n_spec_Y_tag_TRUE) %>%
  pivot_wider(names_from = period, values_from = c(n_spec_Y_tag_FALSE, n_spec_Y_tag_TRUE))

5 Analysis for existing green paths:

p1 %>%
  ggplot(aes(x = n_spec_Y_tag_FALSE, y = n_spec_Y_tag_TRUE)) +
  geom_point(aes(size = n_spec_count_Y_tag_TRUE, col = HHI_Y_tag_TRUE)) +
  geom_text(aes(label = nuts), position = position_dodge(0.9), alpha = 0.75) +
  geom_segment(data = p2, 
               aes(x = n_spec_Y_tag_FALSE_1,
                   y = n_spec_Y_tag_TRUE_1,
                   xend = n_spec_Y_tag_FALSE_2,
                   yend = n_spec_Y_tag_TRUE_2,
                   size = 1),
               alpha = 0.15,
               arrow = arrow(length = unit(0.5, "cm"), type = "closed"),
               show.legend = FALSE) +
  scale_color_gradient2(low = "skyblue", mid = 'yellow', high = "red", midpoint = 1) +
  labs(title = 'Development of new regional specializations', 
       subtitle = 'By number of green and non green specializations in period 1 and 2',
       note = '',
       x = 'N non-green specializations',
       y = 'N green specializations',
       size = 'N green patents',
       col = 'HHI green patents') 


rm(p1, p2)
select_regions_green <- tech_dev %>%
  group_by(nuts, period) %>%
  summarise(green =  sum(Y_tag * rta, na.rm = TRUE),
            green_bin =  sum(Y_tag * rta_bin, na.rm = TRUE),
            n_tech_region =  sum(n_tech_region, na.rm = TRUE),
            n_green_region =  sum(Y_tag * n_tech_region, na.rm = TRUE),
            n_green_rta =  sum(Y_tag * n_tech_region * rta_bin, na.rm = TRUE)) %>%
  ungroup() %>%
  filter(n_green_rta >= n_cutoff,
         green_bin >= 1,
         period == '1') %>%
  select(nuts)
`summarise()` has grouped output by 'nuts'. You can override using the `.groups` argument.
tech_spec_dev <- tech_dev %>%
  filter(n_tech_region >= n_cutoff) %>%
  group_by(nuts, Y_tag) %>%
  summarise(rta_dev = rta_dev %>% sum(na.rm = TRUE)) %>%
  ungroup() %>%
  pivot_wider(names_from = Y_tag, values_from = rta_dev, values_fill = 0, names_prefix = 'Y_spec_')
`summarise()` has grouped output by 'nuts'. You can override using the `.groups` argument.
tech_rel_dev %>%
  group_by(nuts, Y_tag) %>%
  summarise(rel = rel_max %>% mean()) %>%
  ungroup() %>%
  pivot_wider(names_from = Y_tag, values_from = rel, names_prefix = 'Y_', values_fill = 0) %>%
  left_join(tech_dev %>% filter(Y_tag == TRUE, period == '2', rta_bin == 1) %>% select(nuts , n_tech_region) %>% count(nuts, wt = n_tech_region), by = c('nuts')) %>%
  mutate(country = nuts %>% str_sub(1,2)) %>%
  #semi_join(top_regions, by = 'nuts') %>%
  filter(0.5 <= percent_rank(n)) %>%
  ggplot(aes(x = Y_FALSE, y = Y_TRUE, size = n)) +
  geom_point(aes(col = country)) +
  geom_text_repel(aes(label = nuts), box.padding = 0.5, max.overlaps = Inf) +
  theme(legend.position="bottom") + 
    labs(title = 'New green specialization period 2', 
       subtitle = 'By nuts regions',
       note = 'Relatedness is the mean over all new green specializations, per green specialization largest relatedness to former specialization counted',
       x = 'Relatedness non-green',
       y = 'Relatedness green',
       size = 'N green patents') 
tech_rel_dev %>%
  group_by(nuts, Y_tag) %>%
  summarise(rel = rel_max %>% mean()) %>%
  ungroup() %>%
  pivot_wider(names_from = Y_tag, values_from = rel, names_prefix = 'Y_', values_fill = 0) %>%
  left_join(tech_dev %>% filter(Y_tag == TRUE, period == '2', rta_bin == 1) %>% select(nuts , n_tech_region) %>% count(nuts, wt = n_tech_region), by = c('nuts')) %>%
  mutate(country = nuts %>% str_sub(1,2)) %>%
  #semi_join(top_regions, by = 'nuts') %>%
  filter(0.5 <= percent_rank(n)) %>%
  ggplot(aes(x = Y_FALSE, y = Y_TRUE, size = n)) +
  geom_point(aes(col = country)) +
  geom_text_repel(aes(label = nuts), box.padding = 0.5, max.overlaps = Inf) +
  theme(legend.position="bottom") + 
    labs(title = 'New green specialization period 2', 
       subtitle = 'By nuts regions',
       note = 'Relatedness is the mean over all new green specializations, per green specialization largest relatedness to former specialization counted',
       x = 'Relatedness non-green',
       y = 'Relatedness green',
       size = 'N green patents') 
`summarise()` has grouped output by 'nuts'. You can override using the `.groups` argument.

6 TODO

p1 <- tech_rel_dev %>%
  filter(nuts %in% select_region) %>%
  group_by(nuts, nace_group, Y_tag) %>%
  summarise(rel = rel_max %>% mean()) %>%
  ungroup() %>%
  pivot_wider(names_from = Y_tag, values_from = rel, names_prefix = 'Y_', values_fill = 0) %>%
  left_join(tech_dev %>% 
              filter(Y_tag == TRUE, period == '2', rta_bin == 1) %>% 
              select(nuts, nace_group, n_tech_region) %>% 
              count(nuts, nace_group, wt = n_tech_region), 
            by = c('nuts', 'nace_group')) %>%
  mutate(country = nuts %>% str_sub(1,2))
`summarise()` has grouped output by 'nuts', 'nace_group'. You can override using the `.groups` argument.
x_mid <- mean(c(max(p1$Y_FALSE, na.rm = TRUE), 
                min(p1$Y_FALSE, na.rm = TRUE)))

y_mid <- mean(c(max(p1$Y_TRUE, na.rm = TRUE), 
                min(p1$Y_TRUE, na.rm = TRUE)))

# plotting
p1 %>%
  ggplot(aes(x = Y_FALSE, y = Y_TRUE, size = n)) +
  geom_point() +
  geom_text_repel(aes(label = nace_group), box.padding = 0.5) +
  geom_vline(xintercept = x_mid, linetype = "dashed", color = 'grey') + 
  geom_hline(yintercept = y_mid, linetype = "dashed", color = 'grey') +
  facet_wrap(vars(nuts)) +
  labs(title = 'New green specialization period 2', 
       subtitle = 'By nuts regions',
       note = 'Relatedness is the mean over all new green specializations, per green specialization largest relatedness to former specialization counted',
       x = 'Relatedness non-green',
       y = 'Relatedness green',
       size = 'N green patents') 


rm(p1, x_mid, y_mid)
LS0tCnRpdGxlOiAnR3JlZW4gUmVnaW9uYWwgUGF0aCBwYXBlcjogRmlyc3QgcmVzdWx0cycKYXV0aG9yOiAiRGFuaWVsIFMuIEhhaW4iCmRhdGU6ICJgciBmb3JtYXQoU3lzLnRpbWUoKSwgJyVkICVCLCAlWScpYCIKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2s6CiAgICBkZl9wcmludDogcGFnZWQKICAgIHRvYzogeWVzCiAgICB0b2NfZGVwdGg6IDMKICAgIHRvY19mbG9hdDogeWVzCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcwogICAgY29kZV9mb2xkaW5nOiBoaWRlCi0tLQoKYGBge3IsIHNldHVwLCBpbmNsdWRlPUZBTFNFfQojIyMgZ2VuZXJhbCBvcHRpb25zClN5cy5zZXRlbnYoTEFORyA9ICJlbiIpCm9wdGlvbnMoInNjaXBlbiIgPSAxMDAsICJkaWdpdHMiID0gNCkgIyBvdmVycmlkZSBSJ3MgdGVuZGVuY3kgdG8gdXNlIHNjaWVudGlmaWMgbm90YXRpb24KCiMjIyBDbGVhbiB3b3Jrc3BhY2UKcm0obGlzdD1scygpKQpncmFwaGljcy5vZmYoKQoKIyMjIExvYWQgcGFja2FnZXMgKG1heWJlIG5lZWQgdG8gYmUgaW5zdGFsbGVkIGZpcnN0KQojIFN0YW5kYXJkCmxpYnJhcnkodGlkeXZlcnNlKSAjIEdlbmVyYWwgRFMgdG9vbGtpdApsaWJyYXJ5KG1hZ3JpdHRyKSAjIEZvciBhZHZhbmNlZCBwaXBpbmcKCiMgRGF0YWJhc2VzCmxpYnJhcnkoREJJKSAjIEdFbmVyYWwgUiBkYXRhYmFzZSBpbnRlcmZhY2UKbGlicmFyeShSUG9zdGdyZXMpICMgUG9zdGdyZVNRTCBpbnRlcmZhY2UgZHJpdmVyIApsaWJyYXJ5KGRicGx5cikgIyBmb3IgZHBseXIgd2l0aCBkYXRhYmFzZXMKCiMgbmV0d29ya3MKbGlicmFyeSh0aWR5Z3JhcGgpCmxpYnJhcnkoZ2dyYXBoKQpsaWJyYXJ5KGdncmVwZWwpCgojIExvYWQgZnVuY3Rpb25zCnNvdXJjZSgiZnVuY3Rpb25zL2Z1bmN0aW9uc19yZWxhdGVkbmVzcy5SIikKYGBgCgoKIyBJbnRyb2R1Y3Rpb24KCiogSW4gdGhpcyBub3RlYm9vaywgd2UgcHJlc2VudCB0aGUgZmlyc3QgcmVzdWx0cyBvZiBhbiBhbmFseXNpcyBvZiBncmVlbiBkZXZlbG9wbWVudCBwYXRocyBvZiBOb3JkaWMgcmVnaW9ucwoqIEl0IGlzIGJhc2VkIG9uIHBhdGVudCBkYXRhIGZyb20gMTk5MC0yMDE1IChQQVRTVEFULCBBdXR1bW4gMjAyMSBFZGl0aW9uKQoqIEFuYWx5c2lzIGlzIGRvbmUgb24gYWxsIE5vcmRpYyBOVVRTIDIgcmVnaW9ucyAoZnJhY3Rpb25hbGl6ZWQgcGF0ZW50IGFsbG9jYXRpb24gYnkgaW52ZW50b3IgbG9jYXRpb24sIERPQ0RCIGZhbWlseSBsZXZlbCkKKiBJbmR1c3RyaWVzIGFyZSBjYXB0dXJlZCBieSBOQUNFMiBjb2RlcyBvZiBwYXRlbnRzIGFjY29yZGluZyB0byB0aGUgT0VDRCBJUEMtTkFDRTIgY29uY29yZGFuY2UgdGFibGUuCiogR3JlZW4gcGF0ZW50cyBhcmUgaWRlbnRpZmllZCB1c2luZyB0aGUgWTAyIHRhZyBpbiB0aGUgQ1BDIGNsYXNzaWZpY2F0aW9uCgojIyBQcmVwcm9jZXNzaW5nIAoKYGBge3J9CiMjIExPQUQgREFUQQoKIyBSZWd1bGFyIHRhYmxlcwpkYXRhX2FwcGxuIDwtIHJlYWRfcmRzKCcuLi90ZW1wL2RhdGFfYXBwbG4ucmRzJykKZGF0YV9kb2NkYl9mYW1fY3BjIDwtIHJlYWRfcmRzKCcuLi90ZW1wL2RhdGFfZG9jZGJfZmFtX2NwYy5yZHMnKQpkYXRhX3BlcnNfYXBwbG4gIDwtIHJlYWRfcmRzKCcuLi90ZW1wL2RhdGFfcGVyc19hcHBsbi5yZHMnKQpkYXRhX3BlcnNvbiA8LSByZWFkX3JkcygnLi4vdGVtcC9kYXRhX3BlcnNvbi5yZHMnKQpkYXRhX25hY2UyIDwtIHJlYWRfcmRzKCcuLi90ZW1wL2RhdGFfbmFjZTIucmRzJykKCiMgQWRpdHRpb25hbCBvbmVzCmdfdGVjaCA8LSByZWFkX3JkcygnLi4vdGVtcC9nX3RlY2gucmRzJykKcmVnaW9uX1JUQSA8LSByZWFkX3JkcygnLi4vdGVtcC9yZWdpb25fUlRBLnJkcycpCnJlZ2lvbl90ZWNoIDwtIHJlYWRfcmRzKCcuLi90ZW1wL3JlZ2lvbl90ZWNoLnJkcycpCmBgYAoKCmBgYHtyfQojIyBTRUxFQ1QgRk9DVVMgUkVHSU9OUwoKIyMgRGVmaW5pbmcgcGFyYW1ldGVycwpuX3JlZ2lvbnMgPSAxMApuX2N1dG9mZiA9IDI1CnJlZ19pbiA9IGMoJ1NFMjMyJywgJ05PMDQzJywgJ0RLMDEyJykKCiMgUmVzdHJpY3QgdG8gdG9wIE4gcmVnaW9ucwpzZWxlY3RfcmVnaW9uIDwtIHJlZ2lvbl90ZWNoICU+JQogIGdyb3VwX2J5KG51dHMpICU+JQogIHN1bW1hcmlzZShuID0gc3VtKHdlaWdodF9mcmFjLCBuYS5ybSA9IFRSVUUpLAogICAgICAgICAgICBuX1kgPSBzdW0od2VpZ2h0X2ZyYWMgKiBZX3RhZywgbmEucm0gPSBUUlVFKSkgJT4lCiAgdW5ncm91cCgpICU+JQogIG11dGF0ZShzaGFyZV9ZID0gbl9ZIC8gKG4gKyBuX1kpKSAlPiUKICBmaWx0ZXIobl9ZID49IG5fY3V0b2ZmKSAlPiUKICBhcnJhbmdlKGRlc2Mobl9ZKSkgJT4lCiAgbXV0YXRlKGluZGV4ID0gMTpuKCkpICU+JQogIGZpbHRlcihpbmRleCA8PSBuX3JlZ2lvbnMgfCBudXRzICVpbiUgcmVnX2luKSAlPiUKICBkaXN0aW5jdChudXRzKSAlPiUKICBwdWxsKG51dHMpCgpybShuX3JlZ2lvbnMsIHJlZ19pbikKYGBgCgpgYGB7cn0KIyBDcmVhdGVkYXRhZnJhbWUgd2l0aCB0ZWNobm9sb2d5IHJlbGF0ZWRuZXNzIGVkZ2VsaXN0CnRlY2hfcmVsIDwtIGdfdGVjaCAlRT4lCiAgbXV0YXRlKGZyb21fbmFjZSA9IC5OKCkkbmFtZVtmcm9tXSwKICAgICAgICAgdG9fbmFjZSA9IC5OKCkkbmFtZVt0b10pICU+JQogIGFzX3RpYmJsZSgpICU+JQogIG11dGF0ZShmcm9tID0gZnJvbV9uYWNlICU+JSBhcy5jaGFyYWN0ZXIoKSwKICAgICAgICAgdG8gPSB0b19uYWNlICU+JSBhcy5jaGFyYWN0ZXIoKSwKICAgICAgICAgcGN0X3JhbmsgPSB3ZWlnaHQgJT4lIHBlcmNlbnRfcmFuaygpKSAlPiUKICBhcnJhbmdlKGZyb20sIHRvKSAlPiUKICBzZWxlY3QoZnJvbSwgdG8sIHdlaWdodCwgcGN0X3JhbmspCgp0ZWNoX3JlbCAlPD4lCiAgYmluZF9yb3dzKHRlY2hfcmVsICU+JSAKICAgICAgICAgICAgICByZW5hbWUoZnJvbV9uZXcgPSB0bywgdG9fbmV3ID0gZnJvbSkgJT4lIAogICAgICAgICAgICAgIHJlbmFtZShmcm9tID0gZnJvbV9uZXcsIHRvID0gdG9fbmV3KSAlPiUKICAgICAgICAgICAgICByZWxvY2F0ZShmcm9tLCB0bykpICU+JQogIGRpc3RpbmN0KGZyb20sIHRvLCAua2VlcF9hbGwgPSBUUlVFKQpgYGAKCmBgYHtyfQojIGF1Z21lbnQgcmVnaW9ucyBkYXRhIAojIE5PVEU6IERPIGVhcmxpZXIgYWxyZWFkeSBpbiBjb25zdHJ1Y3Rpb24KcmVnaW9uX1JUQSAlPD4lCiAgbXV0YXRlKGNvdW50cnkgPSBudXRzICU+JSBzdHJfc3ViKDEsMikpIApgYGAKCmBgYHtyfQojIFN1bW1hcml6ZSBSZWdpb25zCnJlZ2lvbl9SVEFfYWdnIDwtIHJlZ2lvbl9SVEEgJT4lCiAgZ3JvdXBfYnkobnV0cywgcGVyaW9kLCBZX3RhZykgJT4lCiAgc3VtbWFyaXNlKG5fc3BlYyA9IHJ0YV9iaW4gJT4lIHN1bShuYS5ybSA9IFRSVUUpLAogICAgICAgICAgICBuX3NwZWNfY291bnQgPSAobl90ZWNoX3JlZ2lvbiAqIHJ0YV9iaW4pICU+JSBzdW0obmEucm0gPSBUUlVFKSwKICAgICAgICAgICAgSEhJID0gc3VtKChuX3RlY2hfcmVnaW9uL3N1bShuX3RlY2hfcmVnaW9uKSAqIDEwMCleMikgKSAlPiUKICB1bmdyb3VwKCkgJT4lCiAgbXV0YXRlKGNvdW50cnkgPSBudXRzICU+JSBzdHJfc3ViKDEsMiksCiAgICBudXRzX3BlcmlvZCA9IHBhc3RlKG51dHMsICdQJywgcGVyaW9kKSkgCmBgYAoKYGBge3J9CiMgRGF0YWZyYW1lIHdpdGggcmVnaW9ucyBhbmQgdGVjaG5vbG9neSBmaWVsZHMKdGVjaF9kZXYgPC0gcmVnaW9uX1JUQSAlPiUKICBzZWxlY3QocGVyaW9kLCBjb3VudHJ5LCBudXRzLCBuYWNlX2dyb3VwLCBZX3RhZywgbl90ZWNoX3JlZ2lvbiwgcnRhLCBydGFfYmluKSAlPiUKICBhcnJhbmdlKG51dHMsIG5hY2VfZ3JvdXAsIFlfdGFnLCBwZXJpb2QpIAoKdGVjaF9kZXYgJTw+JSAKICBncm91cF9ieShudXRzLCBuYWNlX2dyb3VwLCBZX3RhZykgJT4lCiAgbXV0YXRlKHJ0YV9kZXYgPSBjYXNlX3doZW4oCiAgICBydGFfYmluIDwgbGFnKHJ0YV9iaW4sIDEpICB+IC0xLAogICAgcnRhX2JpbiA9PSBsYWcocnRhX2JpbiwgMSkgIH4gMCwKICAgIHJ0YV9iaW4gPiBsYWcocnRhX2JpbiwgMSkgIH4gMSAKICApKSAlPiUKICB1bmdyb3VwKCkKYGBgCgojIFBhdGVudCBhcHBsaWNhdGlvbiBkZXZlbG9wbWVudAoKKiBJbiB0aGUgZm9sbG93aW5nLCBhIGJyaWVmIGRlc2NyaXB0aXZlIGFuYWx5c2lzIG9mIHRoZSBkZXZlbG9wbWVudCBvZiBncmVlbiBhbmQgbm9uLWdyZWVuIHBhdGVudCBhcHBsaWNhdGlvbiBpbiB0aGUgTm9yZGljcwoqIEluIGFkZGl0aW9uLCBhIGJyZWFja2Rvd24gb2YgZ3JlZW4gcGF0ZW50cyBieSB0b3AgZ3JlZW4gcGF0ZW50aW5nIHJlYWdpb25zCgpgYGB7cn0KZGF0YV9hcHBsbiAlPiUKICBjb3VudChhcHBsbl9maWxpbmdfeWVhciwgWV90YWcpICU+JQogIGdncGxvdChhZXMoeCA9IGFwcGxuX2ZpbGluZ195ZWFyLCB5ID0gbiwgY29sID0gWV90YWcpKSArIAogIGdlb21fbGluZShrZXlfZ2x5cGggPSAidGltZXNlcmllcyIpICsKICBsYWJzKHRpdGxlID0gJ1BhdGVudCBhcHBsaWNhdGlvbnM6IERldmVsb3BtZW50JywKICAgICAgIHN1YnRpdGxlID0gJ0FsbCBOb3JkaWMgY29udHJpZXMsIGJ5IFkgdGFnJywKICAgICAgIHggPSAnWWVhcicsCiAgICAgICB5ID0gJ051bWJlciBhcHBsaWNhdGlvbnMnLAogICAgICAgY29sID0gJ0dyZWVuJykKYGBgCmBgYHtyfQpkYXRhX3BlcnNfYXBwbG4gJT4lCiAgZmlsdGVyKG51dHMgJWluJSBzZWxlY3RfcmVnaW9uKSAlPiUKICBjb3VudChhcHBsbl9maWxpbmdfeWVhciwgbnV0cywgWV90YWcsIHd0ID0gd2VpZ2h0X2ZyYWMpICU+JQogIGdncGxvdChhZXMoeCA9IGFwcGxuX2ZpbGluZ195ZWFyLCB5ID0gbiwgY29sID0gbnV0cykpICsgCiAgZ2VvbV9saW5lKGtleV9nbHlwaCA9ICJ0aW1lc2VyaWVzIikgKwogIGZhY2V0X3dyYXAodmFycyhZX3RhZyksIHNjYWxlcyA9ICdmcmVlJykgKwogIGxhYnModGl0bGUgPSAnUGF0ZW50IGFwcGxpY2F0aW9uczogRGV2ZWxvcG1lbnQnLAogICAgICAgc3VidGl0bGUgPSAnQWxsIE5vcmRpYyBjb250cmllcycsCiAgICAgICB4ID0gJ1llYXInLAogICAgICAgeSA9ICdOdW1iZXIgYXBwbGljYXRpb25zLCBieSByZWdpb24gYW5kIFkgdGFnJywKICAgICAgIGNvbCA9ICdOdXRzMycpCmBgYAoKIyBUZWNobm9sb2d5IHNwYWNlIGdlbmVyYWwKCiogV2UgY2FsY3VsYXRlIHRoZSByZWxhdGVkbmVzcyBvZiBpbmR1c3RyaWVzIGJ5IGNvLW9jY3VyZW5jZSBwYXR0ZXJuIGZvbGxvd2luZyBIaWRhbGdvICYgSGF1c21hbm4gKDIwMDcpCiogUmV2ZWFsZWQgdGVjaG5vbG9naWNhbCBhZHZhbnRhZ2UgKFJUQSkgSXMgc2VwcGVyYXRlZGx5IGNhbGN1bGF0ZWQgZm9yIFktdGFnIGFuZCBub24tWS10YWcgcGF0ZW50cy4KCmBgYHtyfQpzZXQuc2VlZCgxMzM3KQpjb29yZHNfdGVjaCA8LSBnX3RlY2ggJT4lIGlncmFwaDo6bGF5b3V0LmZydWNodGVybWFuLnJlaW5nb2xkKCkgJT4lIGFzX3RpYmJsZSgpCmNvbG5hbWVzKGNvb3Jkc190ZWNoKSA8LSBjKCJ4IiwgInkiKQpgYGAKCmBgYHtyLCBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9IDEwfQpnX3RlY2ggJU4+JQogIG11dGF0ZShuYWNlX2dyb3VwX25hbWUgPSBuYWNlX2dyb3VwX25hbWUgJT4lIHN0cl90cnVuYyg1MCwgc2lkZSA9ICdyaWdodCcpKSAlPiUKICBnZ3JhcGgobGF5b3V0ID0gIGNvb3Jkc190ZWNoKSArIAogIGdlb21fZWRnZV9saW5rKGFlcyh3aWR0aCA9IHdlaWdodCwgYWxwaGEgPSB3ZWlnaHQpLCBjb2xvdXIgPSAiZ3JleSIpICsgCiAgZ2VvbV9ub2RlX3BvaW50KGFlcyhjb2xvdXIgPSBuYWNlX3NlY19uYW1lLCBzaXplID0gZGdyKSkgKyAKICBnZW9tX25vZGVfdGV4dChhZXMobGFiZWwgPSBuYWNlX2dyb3VwX25hbWUsIHNpemUgPSBkZ3IsIGZpbHRlciA9IHBlcmNlbnRfcmFuayhkZ3IpID49IDAuNSApLCByZXBlbCA9IFRSVUUpICsKICB0aGVtZV92b2lkKCkgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0iYm90dG9tIikgKyAKICBsYWJzKHRpdGxlID0gJ0luZHVzdHJ5IFNwYWNlIChhbGwgTm9yZGljcyknLAogICAgICAgc3VidGl0bGUgPSAnTm9kZXMgPSBOQUNFIDIgSW5kdXN0cmllcy4gRWRnZXM6IFJlbGF0ZWRuZXNzJykKYGBgCgojIFJlZ2lvbmFsIHNwZWNpYWxpemF0aW9uIChSVEEpIGRldmVsb3BtZW50CgoqIENvbXBhcmlzb24gb2Ygc3BlY2lhbGl6YXRpb24gcHJvdmlkZXMgaW4gcGVyaW9kIDEgYW5kIDIKCmBgYHtyfQpwMSA8LSByZWdpb25fUlRBX2FnZyAgJT4lCiAgZmlsdGVyKG51dHMgJWluJSBzZWxlY3RfcmVnaW9uKSAlPiUKICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gWV90YWcsIHZhbHVlc19mcm9tID0gYyhuX3NwZWMsIG5fc3BlY19jb3VudCwgSEhJKSwgdmFsdWVzX2ZpbGwgPSAwLCBuYW1lc19wcmVmaXggPSAnWV90YWdfJykgCgpwMiA8LSBwMSAlPiUgCiAgc2VsZWN0KHBlcmlvZCwgbnV0cywgbl9zcGVjX1lfdGFnX0ZBTFNFLCBuX3NwZWNfWV90YWdfVFJVRSkgJT4lCiAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHBlcmlvZCwgdmFsdWVzX2Zyb20gPSBjKG5fc3BlY19ZX3RhZ19GQUxTRSwgbl9zcGVjX1lfdGFnX1RSVUUpKQpgYGAKCmBgYHtyLCBmaWcud2lkdGg9IDcuNSwgZmlnLmhlaWdodD03LjV9CnAxICU+JQogIGdncGxvdChhZXMoeCA9IG5fc3BlY19ZX3RhZ19GQUxTRSwgeSA9IG5fc3BlY19ZX3RhZ19UUlVFKSkgKwogIGdlb21fcG9pbnQoYWVzKHNpemUgPSBuX3NwZWNfY291bnRfWV90YWdfVFJVRSwgY29sID0gSEhJX1lfdGFnX1RSVUUpKSArCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG51dHMpLCBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDAuOSksIGFscGhhID0gMC43NSkgKwogIGdlb21fc2VnbWVudChkYXRhID0gcDIsIAogICAgICAgICAgICAgICBhZXMoeCA9IG5fc3BlY19ZX3RhZ19GQUxTRV8xLAogICAgICAgICAgICAgICAgICAgeSA9IG5fc3BlY19ZX3RhZ19UUlVFXzEsCiAgICAgICAgICAgICAgICAgICB4ZW5kID0gbl9zcGVjX1lfdGFnX0ZBTFNFXzIsCiAgICAgICAgICAgICAgICAgICB5ZW5kID0gbl9zcGVjX1lfdGFnX1RSVUVfMiwKICAgICAgICAgICAgICAgICAgIHNpemUgPSAxKSwKICAgICAgICAgICAgICAgYWxwaGEgPSAwLjE1LAogICAgICAgICAgICAgICBhcnJvdyA9IGFycm93KGxlbmd0aCA9IHVuaXQoMC41LCAiY20iKSwgdHlwZSA9ICJjbG9zZWQiKSwKICAgICAgICAgICAgICAgc2hvdy5sZWdlbmQgPSBGQUxTRSkgKwogIHNjYWxlX2NvbG9yX2dyYWRpZW50Mihsb3cgPSAic2t5Ymx1ZSIsIG1pZCA9ICd5ZWxsb3cnLCBoaWdoID0gInJlZCIsIG1pZHBvaW50ID0gMSkgKwogIGxhYnModGl0bGUgPSAnRGV2ZWxvcG1lbnQgb2YgbmV3IHJlZ2lvbmFsIHNwZWNpYWxpemF0aW9ucycsIAogICAgICAgc3VidGl0bGUgPSAnQnkgbnVtYmVyIG9mIGdyZWVuIGFuZCBub24gZ3JlZW4gc3BlY2lhbGl6YXRpb25zIGluIHBlcmlvZCAxIGFuZCAyJywKICAgICAgIG5vdGUgPSAnJywKICAgICAgIHggPSAnTiBub24tZ3JlZW4gc3BlY2lhbGl6YXRpb25zJywKICAgICAgIHkgPSAnTiBncmVlbiBzcGVjaWFsaXphdGlvbnMnLAogICAgICAgc2l6ZSA9ICdOIGdyZWVuIHBhdGVudHMnLAogICAgICAgY29sID0gJ0hISSBncmVlbiBwYXRlbnRzJykgCgpybShwMSwgcDIpCmBgYAoKCiMgQW5hbHlzaXMgZm9yIGV4aXN0aW5nIGdyZWVuIHBhdGhzOgoKYGBge3J9CnNlbGVjdF9yZWdpb25zX2dyZWVuIDwtIHRlY2hfZGV2ICU+JQogIGdyb3VwX2J5KG51dHMsIHBlcmlvZCkgJT4lCiAgc3VtbWFyaXNlKGdyZWVuID0gIHN1bShZX3RhZyAqIHJ0YSwgbmEucm0gPSBUUlVFKSwKICAgICAgICAgICAgZ3JlZW5fYmluID0gIHN1bShZX3RhZyAqIHJ0YV9iaW4sIG5hLnJtID0gVFJVRSksCiAgICAgICAgICAgIG5fdGVjaF9yZWdpb24gPSAgc3VtKG5fdGVjaF9yZWdpb24sIG5hLnJtID0gVFJVRSksCiAgICAgICAgICAgIG5fZ3JlZW5fcmVnaW9uID0gIHN1bShZX3RhZyAqIG5fdGVjaF9yZWdpb24sIG5hLnJtID0gVFJVRSksCiAgICAgICAgICAgIG5fZ3JlZW5fcnRhID0gIHN1bShZX3RhZyAqIG5fdGVjaF9yZWdpb24gKiBydGFfYmluLCBuYS5ybSA9IFRSVUUpKSAlPiUKICB1bmdyb3VwKCkgJT4lCiAgZmlsdGVyKG5fZ3JlZW5fcnRhID49IG5fY3V0b2ZmLAogICAgICAgICBncmVlbl9iaW4gPj0gMSwKICAgICAgICAgcGVyaW9kID09ICcxJykgJT4lCiAgc2VsZWN0KG51dHMpCmBgYAoKYGBge3J9CnRlY2hfc3BlY19kZXYgPC0gdGVjaF9kZXYgJT4lCiAgZmlsdGVyKG5fdGVjaF9yZWdpb24gPj0gbl9jdXRvZmYpICU+JQogIGdyb3VwX2J5KG51dHMsIFlfdGFnKSAlPiUKICBzdW1tYXJpc2UocnRhX2RldiA9IHJ0YV9kZXYgJT4lIHN1bShuYS5ybSA9IFRSVUUpKSAlPiUKICB1bmdyb3VwKCkgJT4lCiAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IFlfdGFnLCB2YWx1ZXNfZnJvbSA9IHJ0YV9kZXYsIHZhbHVlc19maWxsID0gMCwgbmFtZXNfcHJlZml4ID0gJ1lfc3BlY18nKQpgYGAKCmBgYHtyfQp0ZWNoX3JlbF9kZXYgPC0gdGVjaF9yZWwgJT4lIAogIHNlbGVjdChmcm9tLCB0bywgd2VpZ2h0KSAlPiUKICBsZWZ0X2pvaW4odGVjaF9kZXYgJT4lIGRpc3RpbmN0KG5hY2VfZ3JvdXAsIG51dHMpLCBieSA9IGMoJ2Zyb20nID0gJ25hY2VfZ3JvdXAnKSkgJT4lCiAgIyBmaWx0ZXIgZm9yIHJ0YSBpbiBwZXJpb2QgMQogIGlubmVyX2pvaW4odGVjaF9kZXYgJT4lIGZpbHRlcihwZXJpb2QgPT0gJzEnLCBydGFfYmluID09IDEpICU+JSBzZWxlY3QobmFjZV9ncm91cCwgbnV0cywgWV90YWcpLCBieSA9IGMoJ3RvJyA9ICduYWNlX2dyb3VwJywgJ251dHMnKSkgJT4lCiAgIyBmaWx0ZXIgZm9yIG5ldyBncmVlbiBzcGVjaWFsaXphdGlvbiBpbiBwZXJpb2QgMgogIHNlbWlfam9pbih0ZWNoX2RldiAlPiUgZmlsdGVyKHBlcmlvZCA9PSAnMicsIHJ0YV9iaW4gPT0gMSwgcnRhX2RldiA9PSAxLCBZX3RhZyA9PSBUUlVFKSwgYnkgPSBjKCdmcm9tJyA9ICduYWNlX2dyb3VwJywgJ251dHMnKSkgJT4lCiAgcmVuYW1lKG5hY2VfZ3JvdXAgPSBmcm9tLCByZWxhdGVkX3RlY2huID0gdG8pICU+JQogIGdyb3VwX2J5KG51dHMsIG5hY2VfZ3JvdXAsIFlfdGFnKSAlPiUKICBzdW1tYXJpc2UocmVsX21heCA9IHdlaWdodCAlPiUgbWF4KCksCiAgICAgICAgICAgIHJlbF9zdW0gPSB3ZWlnaHQgJT4lIHN1bSgpLAogICAgICAgICAgICByZWxfbWVhbiA9IHdlaWdodCAlPiUgbWVhbigpKSAlPiUKICB1bmdyb3VwKCkKYGBgCgpgYGB7ciwgZmlnLndpZHRoPSA3LjUsIGZpZy5oZWlnaHQ9Ny41fQp0ZWNoX3JlbF9kZXYgJT4lCiAgZ3JvdXBfYnkobnV0cywgWV90YWcpICU+JQogIHN1bW1hcmlzZShyZWwgPSByZWxfbWF4ICU+JSBtZWFuKCkpICU+JQogIHVuZ3JvdXAoKSAlPiUKICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gWV90YWcsIHZhbHVlc19mcm9tID0gcmVsLCBuYW1lc19wcmVmaXggPSAnWV8nLCB2YWx1ZXNfZmlsbCA9IDApICU+JQogIGxlZnRfam9pbih0ZWNoX2RldiAlPiUgZmlsdGVyKFlfdGFnID09IFRSVUUsIHBlcmlvZCA9PSAnMicsIHJ0YV9iaW4gPT0gMSkgJT4lIHNlbGVjdChudXRzICwgbl90ZWNoX3JlZ2lvbikgJT4lIGNvdW50KG51dHMsIHd0ID0gbl90ZWNoX3JlZ2lvbiksIGJ5ID0gYygnbnV0cycpKSAlPiUKICBtdXRhdGUoY291bnRyeSA9IG51dHMgJT4lIHN0cl9zdWIoMSwyKSkgJT4lCiAgI3NlbWlfam9pbih0b3BfcmVnaW9ucywgYnkgPSAnbnV0cycpICU+JQogIGZpbHRlcigwLjUgPD0gcGVyY2VudF9yYW5rKG4pKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBZX0ZBTFNFLCB5ID0gWV9UUlVFLCBzaXplID0gbikpICsKICBnZW9tX3BvaW50KGFlcyhjb2wgPSBjb3VudHJ5KSkgKwogIGdlb21fdGV4dF9yZXBlbChhZXMobGFiZWwgPSBudXRzKSwgYm94LnBhZGRpbmcgPSAwLjUsIG1heC5vdmVybGFwcyA9IEluZikgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0iYm90dG9tIikgKyAKICAgIGxhYnModGl0bGUgPSAnTmV3IGdyZWVuIHNwZWNpYWxpemF0aW9uIHBlcmlvZCAyJywgCiAgICAgICBzdWJ0aXRsZSA9ICdCeSBudXRzIHJlZ2lvbnMnLAogICAgICAgbm90ZSA9ICdSZWxhdGVkbmVzcyBpcyB0aGUgbWVhbiBvdmVyIGFsbCBuZXcgZ3JlZW4gc3BlY2lhbGl6YXRpb25zLCBwZXIgZ3JlZW4gc3BlY2lhbGl6YXRpb24gbGFyZ2VzdCByZWxhdGVkbmVzcyB0byBmb3JtZXIgc3BlY2lhbGl6YXRpb24gY291bnRlZCcsCiAgICAgICB4ID0gJ1JlbGF0ZWRuZXNzIG5vbi1ncmVlbicsCiAgICAgICB5ID0gJ1JlbGF0ZWRuZXNzIGdyZWVuJywKICAgICAgIHNpemUgPSAnTiBncmVlbiBwYXRlbnRzJykgCmBgYAoKYGBge3IsIGZpZy53aWR0aD0gNy41LCBmaWcuaGVpZ2h0PTcuNX0KcDEgPC0gdGVjaF9yZWxfZGV2ICU+JQogIGZpbHRlcihudXRzICVpbiUgc2VsZWN0X3JlZ2lvbikgJT4lCiAgZ3JvdXBfYnkobnV0cywgbmFjZV9ncm91cCwgWV90YWcpICU+JQogIHN1bW1hcmlzZShyZWwgPSByZWxfbWF4ICU+JSBtZWFuKCkpICU+JQogIHVuZ3JvdXAoKSAlPiUKICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gWV90YWcsIHZhbHVlc19mcm9tID0gcmVsLCBuYW1lc19wcmVmaXggPSAnWV8nLCB2YWx1ZXNfZmlsbCA9IDApICU+JQogIGxlZnRfam9pbih0ZWNoX2RldiAlPiUgCiAgICAgICAgICAgICAgZmlsdGVyKFlfdGFnID09IFRSVUUsIHBlcmlvZCA9PSAnMicsIHJ0YV9iaW4gPT0gMSkgJT4lIAogICAgICAgICAgICAgIHNlbGVjdChudXRzLCBuYWNlX2dyb3VwLCBuX3RlY2hfcmVnaW9uKSAlPiUgCiAgICAgICAgICAgICAgY291bnQobnV0cywgbmFjZV9ncm91cCwgd3QgPSBuX3RlY2hfcmVnaW9uKSwgCiAgICAgICAgICAgIGJ5ID0gYygnbnV0cycsICduYWNlX2dyb3VwJykpICU+JQogIG11dGF0ZShjb3VudHJ5ID0gbnV0cyAlPiUgc3RyX3N1YigxLDIpKSAlPiUKICBsZWZ0X2pvaW4oKQoKeF9taWQgPC0gbWVhbihjKG1heChwMSRZX0ZBTFNFLCBuYS5ybSA9IFRSVUUpLCAKICAgICAgICAgICAgICAgIG1pbihwMSRZX0ZBTFNFLCBuYS5ybSA9IFRSVUUpKSkKCnlfbWlkIDwtIG1lYW4oYyhtYXgocDEkWV9UUlVFLCBuYS5ybSA9IFRSVUUpLCAKICAgICAgICAgICAgICAgIG1pbihwMSRZX1RSVUUsIG5hLnJtID0gVFJVRSkpKQoKIyBwbG90dGluZwpwMSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBZX0ZBTFNFLCB5ID0gWV9UUlVFLCBzaXplID0gbikpICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fdGV4dF9yZXBlbChhZXMobGFiZWwgPSBuYWNlX2dyb3VwKSwgYm94LnBhZGRpbmcgPSAwLjUpICsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSB4X21pZCwgbGluZXR5cGUgPSAiZGFzaGVkIiwgY29sb3IgPSAnZ3JleScpICsgCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0geV9taWQsIGxpbmV0eXBlID0gImRhc2hlZCIsIGNvbG9yID0gJ2dyZXknKSArCiAgZmFjZXRfd3JhcCh2YXJzKG51dHMpKSArCiAgbGFicyh0aXRsZSA9ICdOZXcgZ3JlZW4gc3BlY2lhbGl6YXRpb24gcGVyaW9kIDInLCAKICAgICAgIHN1YnRpdGxlID0gJ0J5IG51dHMgcmVnaW9ucycsCiAgICAgICBub3RlID0gJ1JlbGF0ZWRuZXNzIGlzIHRoZSBtZWFuIG92ZXIgYWxsIG5ldyBncmVlbiBzcGVjaWFsaXphdGlvbnMsIHBlciBncmVlbiBzcGVjaWFsaXphdGlvbiBsYXJnZXN0IHJlbGF0ZWRuZXNzIHRvIGZvcm1lciBzcGVjaWFsaXphdGlvbiBjb3VudGVkJywKICAgICAgIHggPSAnUmVsYXRlZG5lc3Mgbm9uLWdyZWVuJywKICAgICAgIHkgPSAnUmVsYXRlZG5lc3MgZ3JlZW4nLAogICAgICAgc2l6ZSA9ICdOIGdyZWVuIHBhdGVudHMnKSAKCnJtKHAxLCB4X21pZCwgeV9taWQpCmBgYAoKIyBUT0RPCgoqIExhYmVsIDJuZCBmaWd1cmUgb24gZ3JlZW4sIGxhYmVsIGNvaW5jaWRpbmcsIG1heWJlIHJ0YSwgc2hhcmUgb3IgZ3Jvd3RoCiogRG8gc29tZSByYWRhciBwbG90dGluZywgZWc6IGh0dHBzOi8vci1ncmFwaC1nYWxsZXJ5LmNvbS93ZWItY2lyY3VsYXItYmFycGxvdC13aXRoLVItYW5kLWdncGxvdDIuaHRtbCAKCmBgYHtyfQpzZXNzaW9uSW5mbygpCmBgYAoKCg==